package com.zpself.module.多线程.Lock;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author By ZengPeng
 * @Description
 * @date in  2021/3/6 12:32
 * @Modified By
 */
public class Condition分析 {
    public ReentrantLock lock = new ReentrantLock();
    public Condition c1 = lock.newCondition();
    public Condition c2 = lock.newCondition();
    public Condition c3 = lock.newCondition();
    static volatile AtomicInteger number = new AtomicInteger(500);

    public CountDownLatch cd =new CountDownLatch(1);

    @Test
    //循环打印ABC  500次
    public void test() throws InterruptedException {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        pool.execute(() -> {
            lock.lock();
            System.out.println("A抢到锁了");
            while (number.get() > 0) {
                try {
                    System.out.print("A " );
                    //阻塞当前线程，加入等待队列，释放lock
                    c2.signal();
                    c1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            lock.unlock();
            System.out.println("A关闭了锁");
            cd.countDown();
        });

        pool.execute(() -> {
            lock.lock();
            System.out.println("B抢到锁了");
            while (number.get() > 0) {
                try {
                    System.out.print("B ");
                    c3.signal();
                    c2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        pool.execute(() -> {
            lock.lock();
            System.out.println("C抢到锁了");
            while (number.get() > 0) {
                try {
                    System.out.print("C 数字=" +number.get());
                    System.out.println();
                    number.getAndDecrement();
                    c1.signal();
                    c3.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        cd.await();//这里主要是让主线程等待打印完成
        System.out.println("打印完毕");
    }


    //测试不获取锁能直接 await()、signal 吗
    @Test
    public void  test2() throws InterruptedException {
        lock.lock();
        c1.await();
        System.out.println("直接等待...");
        lock.unlock();
    }
}
